/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @addtogroup Camera
 * @{
 *
 * @brief Camera模块接口定义。
 *
 * camera模块涉及相机设备的操作、流的操作、离线流的操作和各种回调等。
 *
 * @since 1.0
 */

/**
 * @file types.h
 *
 * @brief Camera模块HDI接口使用的数据类型。
 *
 * @since 1.0
 * @version 1.0
 */

#ifndef CAMERA_DEVICE_DRIVER_TYPES_H
#define CAMERA_DEVICE_DRIVER_TYPES_H

#include <functional>
#include <memory>
#include <string>
#include <vector>
#include <surface.h>
#include "camera_metadata_info.h"
#include "type_common.h"

namespace OHOS::Camera {
using CameraAbility = CameraMetadata;
using CameraSetting = CameraMetadata;

/**
 * @brief HDI接口的返回值。
 */
enum CamRetCode : int32_t {
    /**
     * 调用成功。
     */
    NO_ERROR = 0,

    /**
     * 设备当前忙。
     */
    CAMERA_BUSY = -1,

    /**
     * 资源不足。
     */
    INSUFFICIENT_RESOURCES = -2,

    /**
     * 参数错误。
     */
    INVALID_ARGUMENT = -3,

    /**
     * 不支持当前调用方法。
     */
    METHOD_NOT_SUPPORTED = -4,

    /**
     * Camera设备已经关闭。
     */
    CAMERA_CLOSED = -5,

    /**
     * 驱动层发生严重错误。
     */
    DEVICE_ERROR = -6,
};

/**
 * @brief metadata的上报模式。
 */
enum ResultCallbackMode : int32_t {
    /**
     * 每帧上报。
     */
    PER_FRAME,

    /**
     * 设备状态变化时上报。
     */
    ON_CHANGED
};

/**
 * @brief 流的使用模式。
 */
enum OperationMode : int32_t {
    /**
     * 普通模式。
     */
    NORMAL = 0,
};

/**
 * @brief 流的类型。
 */
enum StreamIntent : int32_t {
    /**
     * 流数据用于显示，即预览流。
     */
    PREVIEW = 0,

    /**
     * 流数据用于编码生成录像，即录像流。
     */
    VIDEO = 1,

    /**
     * 流数据用于编码生成照片，即拍照流。
     */
    STILL_CAPTURE = 2,

    /**
     * 流数据用于保存缩略图。
     */
    POST_VIEW = 3,

    /**
     * 流数据用于图像分析。
     */
    ANALYZE = 4,

    /**
     * 自定义类型。
     */
    CUSTOM = 5,
};

/**
 * @brief 流数据的编码类型。
 */
enum EncodeType : int32_t {
    /**
     * 未设置编码类型
     */
    ENCODE_TYPE_NULL = 0,

    /**
     * 编码类型为H264。
     */
    ENCODE_TYPE_H264 = 1,

    /**
     * 编码类型为H265。
     */
    ENCODE_TYPE_H265 = 2,

    /**
     * 编码类型为JPEG。
     */
    ENCODE_TYPE_JPEG = 3,
};

/**
 * @brief 流信息，用于创建流时传入相关的配置参数。
 */
struct StreamInfo {
    /**
     * 流的ID，用于在设备内唯一标识一条流。
     */
    int streamId_;

    /**
     * 图像宽度。
     */
    int width_;

    /**
     * 图像高度。
     */
    int height_;

    /**
     * 图像格式。
     */
    int format_;

    /**
     * 图像颜色空间。
     */
    int datasapce_;

    /**
     * 流类型。
     */
    StreamIntent intent_;

    /**
     * 隧道模式，值为true时开启，false关闭。
	 *
	 * 开启隧道模式后，HAL不直接和上层交互，通过图形提供的生产者句柄来传递帧数据，
     * 对于一些IOT设备，可能不需要或者不支持预览流的图像数据缓存流转，此时需要关闭隧道模式。
     */
    bool tunneledMode_;

    /**
     * 图形提供的生产者句柄。
     */
    OHOS::sptr<OHOS::IBufferProducer> bufferQueue_;

    /**
     * 最小帧间隔。
     */
    int minFrameDuration_;

    /**
     * 编码类型。
     */
    EncodeType encodeType_;
};

/**
 * @brief 动态配置流的切换方式，使用场景参考 {@link IsStreamsSupported}。
 */
enum StreamSupportType : int32_t {
    /**
     * 支持动态配置流，对应的流参数直接生效。
     */
    DYNAMIC_SUPPORTED,

    /**
     * 不支持动态配置流，对应的参数需要停止流然后重新配置流才能生效。
     */
    RE_CONFIGURED_REQUIRED,

    /**
     * 不支持对应的流参数配置。
     */
    NOT_SUPPORTED,
};

/**
 * @brief 流的属性。
 */
struct StreamAttribute {
    /**
     * 流的ID，用于在设备内唯一标识一条流。
     */
    int streamId_;

    /**
     * 图像宽度。
     */
    int width_;

    /**
     * 图像高度。
     */
    int height_;

    /**
     * 重写的图像格式。
     */
    int overrideFormat_;

    /**
     * 重写的图像颜色空间
     */
    int overrideDatasapce_;

    /**
     * 重写后的生产者的使用方式。
     */
    int producerUsage_;

    /**
     * 重写后的生产者缓存数量。
     */
    int producerBufferCount_;

    /**
     * 连拍支持的最大捕获帧数量。
     */
    int maxBatchCaptureCount_;

    /**
     * 最大的并发捕获请求个数，默认为1。
    */
    int maxCaptureCount_;
};

/**
 * @brief 捕获请求的相关信息。
 */
struct CaptureInfo {
    /**
     * 捕获的流ID集合。
    */
    std::vector<int> streamIds_;

    /**
     * 捕获的配置信息。
     */
    std::shared_ptr<CameraMetadata> captureSetting_;

    /**
     * 使能捕获回调，每一次捕获后都会触发 {@link OnFrameShutter}。
    */
    bool enableShutterCallback_;
};

/**
 * @brief Camera设备状态。
 */
enum CameraStatus {
    /**
     * 设备当前不在位或者不可用。
     */
    UN_AVAILABLE = 0,

    /**
     * 设备当前可用。
     */
    AVAILABLE = 1,
};

/**
 * @brief 闪光灯状态。
 */
enum FlashlightStatus : uint32_t {
    /**
     * 闪光灯关闭。
     */
    FLASHLIGHT_OFF = 0,

    /**
     * 闪光灯开启。
     */
    FLASHLIGHT_ON = 1,

    /**
     * 闪光灯当前不可用。
     */
    FLASHLIGHT_UNAVAILABLE = 2,
};

/**
 * @brief Camera事件。
 */
enum CameraEvent : uint32_t {
    /**
     * Camera设备增加事件。
     */
    CAMERA_EVENT_DEVICE_ADD = 0,

    /**
     * Camera设备删除事件。
     */
    CAMERA_EVENT_DEVICE_RMV = 1,
};

/**
 * @brief 设备错误类型，用于设备错误回调 {@link OnError}。
 */
enum ErrorType : uint32_t {
    /**
     * 严重错误，需要关闭camera设备。
     */
    FATAL_ERROR = 0,

    /**
     * 请求超时，需要关闭camera设备。
     */
    REQUEST_TIMEOUT = 1,
};

/**
 * @brief 捕获结束相关信息，用于捕获结束回调 {@link OnCaptureEnded}。
 */
struct CaptureEndedInfo {
    /**
     *  捕获的流ID。
     */
    int streamId_;

    /**
     * 捕获结束时已经抓取的帧数。
     */
    int frameCount_;
};

/**
 * @brief 流错误类型，用于流错误类型 {@link CaptureErrorInfo}。
 */
enum StreamError {
    /**
     * 流未知错误。
     */
    UNKNOWN_ERROR = 0,

    /**
     * 丢包。
     */
    BUFFER_LOST = 1,
};

/**
 * @brief 流错误信息，用于回调 {@link OnCaptureError}。
 */
struct CaptureErrorInfo {
    /**
     *  流Id。
     */
    int streamId_;

    /**
     * 错误类型。
     */
    StreamError error_;
};

/**
 * @brief 采用using来给int32_t类型取一个别名。
 */
using MetaType = int32_t;
}
#endif /** CAMERA_DEVICE_DRIVER_TYPES_H